package com.sx.manage.controller.base;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.regex.Pattern;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.validation.Validator;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.sx.cache.Cache;
import com.sx.cache.Session;
import com.sx.common.util.json.JackJsonUtil;
import com.sx.manage.biz.report.IMReportBiz;
import com.sx.manage.exception.MNotHaveLoginException;
import com.sx.manage.exception.MNotHaveLoginExceptionAjax;
import com.sx.manage.service.company.IMBaseCompanyService;
import com.sx.manage.service.report.IMPayrollCountInfoService;
import com.sx.manage.service.report.IMPersonalConsumerCountInfoService;
import com.sx.manage.service.report.IMProfitCountService;
import com.sx.manage.service.report.IMTradeCountInfoService;
import com.sx.manage.servlet.ViewAndModel;
import com.sx.manage.util.SessionManager;
import com.sx.model.constants.type.MUrlType;
import com.sx.model.manage.mybatis.form.BaseForm;
import com.sx.model.manage.mybatis.vo.consumer.login.MConsumerLoginVO;
import com.sx.model.manage.mybatis.vo.result.ResultListVO;
import com.trusdom.commons.Cryptos;


/**
 * spring 基础控制器
 * 
 * @author lenovo
 *
 */
@Controller
@RequestMapping("/base")
public class MBaseController {
	/**
	 * 日志
	 */
	private Logger log = LoggerFactory.getLogger(this.getClass());
	/**
	 * token超时时间
	 */
	private static final Integer LOGIN_TOKEN_VOER_TIME = 604800;

	@Resource(name = "redisCache")
	protected Cache cache;

	@Autowired
	protected HttpServletRequest request;

	@Autowired
	protected HttpServletResponse response;

	@Resource(name = "mBaseCompanyServiceImpl")
	private IMBaseCompanyService mBaseCompanyServiceImpl;

	@Resource(name = "mPersonalConsumerCountInfoServiceImpl")
	private IMPersonalConsumerCountInfoService mPersonalConsumerCountInfoServiceImpl;
	@Resource(name = "mTradeCountInfoServiceImpl")
	private IMTradeCountInfoService mTradeCountInfoServiceImpl;
	@Resource(name = "payrollCountInfoServiceImpl")
	private IMPayrollCountInfoService payrollCountInfoServiceImpl;
	@Resource(name = "profitCountInfoServiceImpl")
	private IMProfitCountService profitCountInfoServiceImpl;
	@Resource(name = "reportBizImpl")
	private IMReportBiz reportBizImpl;
	/// http 超时时间设置
	private static int TIMEOUT = 100000;
	// 主动校验 前台传入的数据格式
	@Autowired
	protected Validator validator;

	/**
	 * 使用spring 自带的类封装时，日期格式需要特殊处理
	 * 
	 * @param binder
	 */
	@InitBinder
	protected void initBinder(WebDataBinder binder) {
		binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"), true));
	}

	/**
	 * 系统登录页
	 */
	@RequestMapping(value = "loginIndex")
	public ViewAndModel loginIndex(HttpServletRequest request, HttpServletResponse response) {

		return new ViewAndModel("entry/m_entry", request, cache);
	}

	/**
	 * 系统登录页
	 */
	@RequestMapping(value = "index_ftl")
	public ViewAndModel index_ftl(HttpServletRequest request, HttpServletResponse response) {
		return new ViewAndModel("index", request, cache);
	}

	/**
	 * 系统登录页
	 */
	@RequestMapping(value = "index_data")
	public ViewAndModel index_data(HttpServletRequest request, HttpServletResponse response) {
		return new ViewAndModel("indexData", request, cache);
	}

	/**
	 * 系统登录页 method=RequestMethod.GET
	 */
	@RequestMapping(value = "index")
	public ViewAndModel index(HttpServletRequest request, HttpServletResponse response) {
		return new ViewAndModel("entry/m_entry", request, cache);
	}

	/** 首页数据统计 **/
	@RequestMapping(value = "indexData")
	@ResponseBody
	public ResultListVO<Object> _indexData() {
		ResultListVO<Object> result = new ResultListVO<>();
		return result;
	}

	// 生成token字符串
	public static String createStrForToken(MConsumerLoginVO loginVO) {
		if (null == loginVO) {
			return null;
		}
		StringBuilder strBuff = new StringBuilder();
		strBuff.append(loginVO.getConsumer_id());

		return Cryptos.encode(strBuff.toString());
	}

	/**
	 * 获取当前用户信息
	 * 
	 * @param request
	 * @return
	 */
	public MConsumerLoginVO loginConsumer(MUrlType urlType) {
		if (MUrlType.AXAJ_URL.equals(urlType)) {
			return this.loginConsumer();
		} else if (MUrlType.MODEL_AND_VIEW_URL.equals(urlType)) {
			MConsumerLoginVO userVO = null;
			Session session = SessionManager.instance(request, response, cache);
			// 判断当前的用户是否登陆
			if (session.istokenexists()) {
				String userJson = session.get("user");
				if (StringUtils.isNotBlank(userJson)) {
					log.debug("用户信息为空：");
					userVO = JackJsonUtil.jsonToJavaBean(userJson, MConsumerLoginVO.class);
				}
				// 获取 护具
			}
			if (null == userVO) {
				throw new MNotHaveLoginException();// 返回到配置文件中定义的路径
			}
			return userVO;
		}
		return null;
	}

	/**
	 * 获取当前用户信息
	 * 
	 * @param request
	 * @return
	 */
	public MConsumerLoginVO loginConsumer() {
		MConsumerLoginVO userVO = null;
		Session session = SessionManager.instance(request, response, cache);
		// 判断当前的用户是否登陆
		if (session.istokenexists()) {
			String userJson = session.get("user");
			if (StringUtils.isNotBlank(userJson)) {
				userVO = JackJsonUtil.jsonToJavaBean(userJson, MConsumerLoginVO.class);
			}
			// 获取 护具
		}
		if (null == userVO) {
			throw new MNotHaveLoginExceptionAjax();
			// 返回到配置文件中定义的路径
		}
		return userVO;
	}

	/**
	 * 获取请求
	 * 
	 * @param req
	 * @return
	 * @throws IOException
	 */
	protected String extract_param_from_request(HttpServletRequest req) {
		ByteArrayOutputStream output = new ByteArrayOutputStream();
		InputStream is = null;
		try {
			is = req.getInputStream();
			IOUtils.copy(is, output);
		} catch (Exception e) {
			log.error("request to string 异常error={}", e);
		} finally {
			if (null != is) {
				try {
					is.close();
				} catch (IOException e) {
					log.error("InputStream is close() 异常error={}", e);
				}
			}
			if (null != output) {
				try {
					output.close();
				} catch (IOException e) {
					log.error("ByteArrayOutputStream is close() 异常error={}", e);
				}
			}
		}
		if (null != output) {
			try {
				return output.toString("UTF-8");
			} catch (UnsupportedEncodingException e) {
				log.error("output.toString 异常error={}", e);
			}
		}
		return null;

	}

	/*** 字段格式验证 ***/
	public String fieldValidate(BaseForm form, BindingResult errors) {
		// 数据检验(第一种方式)
		validator.validate(form, errors);
		if (errors.hasErrors()) {
			String error = errorsMessage(errors);
			log.error(error);
			return error;
		}
		return null;
	}

	/*** 错误信息提示处理 ***/
	public String errorsMessage(org.springframework.validation.Errors errors) {
		if (errors.hasErrors() || errors.hasGlobalErrors()) {
			StringBuilder errInfo = new StringBuilder();
			List<FieldError> ferrors = errors.getFieldErrors();
			if (!ferrors.isEmpty()) {
				for (FieldError error : ferrors) {
					errInfo.append(error.getField() + ":" + error.getDefaultMessage() + ";");
					log.error(error.getDefaultMessage());
				}
			}
			List<ObjectError> gerrors = errors.getGlobalErrors();
			if (!gerrors.isEmpty()) {
				for (ObjectError error : gerrors) {
					errInfo.append(error.getDefaultMessage() + ";;");
				}
			}
			errors.reject(null, errInfo.toString());
			return errInfo.toString();
		}
		return "";
	}

	/**
	 * 获取请求
	 * 
	 * @param req
	 * @return
	 * @throws IOException
	 */
	protected String extractParamFromRequest(HttpServletRequest req) throws IOException {
		ByteArrayOutputStream output;
		InputStream is = req.getInputStream();
		output = new ByteArrayOutputStream();
		try {
			IOUtils.copy(is, output);
		} catch (Exception e) {
			log.error("属性复制出错error={}", e);
		} finally {
			is.close();
			output.close();
		}
		return output.toString("UTF-8");
	}

	public boolean is_num(String str) {
		// 带小数的
		Pattern pattern = Pattern.compile("^[-+]?[0-9]+(\\.[0-9]+)?$");
		return pattern.matcher(str).matches();
	}

	public IMBaseCompanyService getmBaseCompanyServiceImpl() {
		return mBaseCompanyServiceImpl;
	}

	public void setmBaseCompanyServiceImpl(IMBaseCompanyService mBaseCompanyServiceImpl) {
		this.mBaseCompanyServiceImpl = mBaseCompanyServiceImpl;
	}

	public Cache getCache() {
		return cache;
	}

	public void setCache(Cache cache) {
		this.cache = cache;
	}

	public HttpServletRequest getRequest() {
		return request;
	}

	public void setRequest(HttpServletRequest request) {
		this.request = request;
	}

	public HttpServletResponse getResponse() {
		return response;
	}

	public void setResponse(HttpServletResponse response) {
		this.response = response;
	}

	public static int getTIMEOUT() {
		return TIMEOUT;
	}

	public static void setTIMEOUT(int tIMEOUT) {
		TIMEOUT = tIMEOUT;
	}

	public Validator getValidator() {
		return validator;
	}

	public void setValidator(Validator validator) {
		this.validator = validator;
	}

	public static Integer getLoginTokenVoerTime() {
		return LOGIN_TOKEN_VOER_TIME;
	}

	/** **/
	public ViewAndModel createView() {
		return new ViewAndModel(request, cache);
	}

}
